# !/usr/bin/python
# -*-coding:utf-8 -*-
"""
@File    :   serializers.py
@Create  :   2021/8/28 18:35
@Author  :   David
"""
import re

from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

from .models import User


class CreateUserSerializer(serializers.ModelSerializer):
    """注册序列化器"""

    # 序列化器的所有字段: ['id', 'username', 'password', 'password2', 'mobile']
    # 需要校验的字段: ['username', 'password', 'password2', 'mobile']
    # 模型中已存在的字段: ['id', 'username', 'password', 'mobile']
    # 需要序列化的字段: ['id', 'username', 'mobile', 'token']
    # 需要反序列化的字段: ['username', 'password', 'password2', 'mobile'
    password2 = serializers.CharField(label='确认密码', write_only=True)  # write_only=True只做反系列化
    token = serializers.CharField(label='token', read_only=True)

    class Meta:
        model = User  # 从User模型中映射序列化器字段
        fields = ['id', 'username', 'password', 'password2', 'mobile']
        extra_kwargs = {  # 修改字段选项
            'username': {
                'min_length': 5,
                'max_length': 15,
                'error_messages': {  # 自定义校验出错后的错误信息提示
                    'min_length': '仅允许5-15个字符的用户名',
                    'max_length': '仅允许5-15个字符的用户名',
                }
            },
            'password': {
                'write_only': True,
                'min_length': 6,
                'max_length': 20,
                'error_messages': {
                    'min_length': '仅允许6-20个字符的密码',
                    'max_length': '仅允许6-20个字符的密码',
                }
            }
        }

    def validate_mobile(self, value):
        """单独校验手机号"""
        if re.match(r'1[3-9]\d{9}', value):
            raise serializers.ValidationError('手机号格式有误')
        return value

    def validate(self, attrs):
        """校验两个密码是否相同"""
        if attrs['password'] != attrs['password2']:
            raise serializers.ValidationError('两个密码不一致')
        return attrs

    def create(self, validated_data):
        # 把不需要存储的 password2从字段中移除
        del validated_data['password2']
        # 把密码先取出来
        password = validated_data.pop('password')

        # 创建用户模型对象, 给模型中的 username和mobile属性赋值
        user = User(**validated_data)
        user.set_password(password)  # 把密码加密后再赋值给user的password属性
        user.save()  # 存储到数据库

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER  # 引用jwt中的jwt_payload_handler函数(生成payload)
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER  # 函数引用生成jwt

        payload = jwt_payload_handler(user)  # 根据user生成用户相关的载荷
        token = jwt_encode_handler(payload)  # 传入载荷生成完整的jwt
        user.token = token
        return user
